<template>
  <div>
    <!-- el-card 卡片组件   会显示阴影 -->
    <el-card class="box-card" style="margin: 10px 0px">
      <!-- @GetCategorySelectId  接收子组件传入的数据 
          :Setdisabled   父组件传入数据给子组件
      -->
      <CateGorySelect @GetCategorySelectId="GetCategorySelectId"  :Setdisabled='setdisabled'/>
    </el-card>

    <!-- el-card 卡片组件   会显示阴影 -->
    <el-card class="box-card">
      
      <!-- 点击添加属性按钮时  则隐藏该内容 -->
      <div v-show="setFleg">
          <!-- disabled  是否禁用-->
        <el-button type="primary" icon="el-icon-plus" :disabled="getdisabled" @click="addAttribute">添加属性</el-button>
        <!-- :data需要展示的数据 -->
        <el-table :data="Category" border style="width: 100%; margin: 10px 0px">
          <!-- align  对其方式    type=index   显示索引（从1开始）-->
          <el-table-column label="序号" width="80" align="center" type="index"></el-table-column>
          <!-- property   需要展示的Category的property  数据 -->
          <el-table-column label="属性名称" width="180" align="center" property="attrName"></el-table-column>
          <el-table-column label="属性值列表" property="attrValueList" width="600" align="center">
            <!-- 插值显示数据
                row 为attrValueList的数据 $index为索引
             -->
            <template slot-scope="{ row, $index }">
              <!-- el-tag   标签组件
                   effect   主题
                   :disable-transitions="true"   禁用进入与移出动画效果     
              -->
              <el-tag effect="dark" type="success" v-for="ro in row.attrValueList" :key="ro.id" style="margin: 10px" :disable-transitions="true">{{ ro.valueName }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center">
            <!-- 插值显示数据 -->
            <template slot-scope="{row,$index}">
             <!-- row 为点击了修改的当前数据 -->
              <el-button type="warning" icon="el-icon-edit" style="margin:0px 10px" size="mini" @click="addAttribute(row)">修改</el-button>
              <!-- el-popconfirm 气泡确认框组件   点击了一个按钮则会出现一个气泡弹窗
                    @onConfirm   点击了确认则会调用该方法   （低版本vue模板的事件为onConfirm  高版本 则为 confirm）
                    confirm  点击确认事件
               -->
              <el-popconfirm :title="`确定删除${row.attrName}吗`" @onConfirm='confirm(row)'>
                <!-- slot为气泡确认框的组合用法 -->
                <el-button type="danger" icon="el-icon-delete" size="mini" slot="reference" >删除</el-button>
              </el-popconfirm>

            </template>
          </el-table-column>
        </el-table>
      </div>
     

      

    <!-- 如果点击了添加数据则显示内容  没有点击则隐藏 -->
      <div v-show="!setFleg">
        <!-- :inline  行内表单模式 -->
        <el-form :inline="true" ref="form" >
          <el-form-item label="属性名">
            <!-- 双向绑定输入的数据 并且取消前后空格   trim -->
            <el-input autocomplete="off" size="small" placeholder="请输入属性名" v-model.trim="baseAttrInfo.attrName"></el-input>
          </el-form-item>
        </el-form>
        <!-- :disabled  是否禁用
            如果输入框有内容  则不禁用  没有则禁用
         -->
        <el-button type="primary" icon="el-icon-plus" :disabled='baseAttrInfo.attrName==""' @click="PustValue">添加属性值</el-button>
        <el-button @click="Cancel">取消</el-button>

        <!-- :data   展示需要展示的数据 -->
        <el-table border style="width: 100%;margin:20px 0px" :data="baseAttrInfo.attrValueList">
          <!-- 索引方式显示   type=index -->
          <el-table-column label="序号" width="90" align="center" type="index"></el-table-column>
          <!-- prop 传入table中的 :data 中数据 -->
          <el-table-column label="属性值名称" width="500" align="center" prop="valueName">
            <!-- row获取传入的数据  $index  索引 -->
            <template slot-scope="{row,$index}">
              <!-- 双向绑定输入框的数据   @blur 失去焦点时调用  、
                @keyup.native  把组件转化为为html(组件则会出现这种情况).enter 按回车时调用    把input输入框 转化为  span只读 
                一开始则显示  input 输入框  
                ref  获取input的实例   :ref="$index  把所有的input获取的实例名设置为索引值
              -->
              <el-input v-model="row.valueName" size="mini"  @blur="RemoveOut(row)" 
                  @keyup.native.enter="row.setInput=false"  placeholder="请输入属性名称" v-show="row.setInput" :ref="$index"></el-input>
              <!-- v-show="!row.setInput"   如果input失去焦点  则显示 span 只读    
                  @click="SerInputFocus(row,$index)  点击时把点击的数据与索引传入给点击数据   
                  display：block        因为span是行内标签 大小比较小  则需要转化为 块级标签 
              -->
              <span v-show="!row.setInput" @click="SerInputFocus(row,$index)"  style="display:block">{{row.valueName}}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center">
            <!-- 插值数据 -->
            <template slot-scope="{row,$index}">
              <!-- @click="DeleteRow($index)   把点击的索引传入给DeleteRow事件 -->
              <el-button type="danger" icon="el-icon-delete" size="mini" @click="DeleteRow($index)"></el-button>
            </template>
          </el-table-column>
        </el-table>

        <el-button type="primary" icon="el-icon-plus" @click="Preserve" :disabled='baseAttrInfo.attrValueList<1'>保存</el-button>
        <el-button @click="Cancel">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script>
export default {
  name: "Attr",
  data() {
    return {
      Category: [], //获取属性列表（子组件传入选择的数据接口）
      category3Id: "",  //子组件的3id
      category2Id: "",  //子组件的2id  
      category1Id: "",  //子组件的1id
      setFleg: true,    //是否显示添加属性内容
      setdisabled:false,  //子组件的选择框是否禁用
      // 需要传入保存的数据
      baseAttrInfo:{
        attrName: "", //属性名
        attrValueList: [  //多个属性值数据
        ],
        categoryId: 0,   //category3Id
        categoryLevel: 3, //默认为3
        }
      };
  },
  computed: {
    // 是否禁用添加属性按钮  如果有3id 则说明已经点击完了 则显示可以点击
    getdisabled() {
      if (this.category3Id) {
        return false;
      } else {
        return true;
      }
    },
  },
  methods: {

    // 获取子组件传入的数据   说明点击完成了id3  则可以发送获取属性列表接口
    async GetCategorySelectId(getIds) {
      let result = await this.$API.attr.attrInfoList(getIds);
      if (result.code == 200) {
        // 获取接口返回的数据
        this.Category = result.data;
        this.category1Id = getIds.category1Id;
        this.category2Id = getIds.category2Id;
        this.category3Id = getIds.category3Id;
        // 把3id 赋值给id  因为获取的数据3id都是相同的 所以一开始则赋值
        this.baseAttrInfo.categoryId = getIds.category3Id
      }
    },
    // 点击添加属性方法 与修改属性方法 
    // 传入当前 点击修改按钮的数据 （row）
    addAttribute(row) {
      // 如果点击修改则会有name值
      if (row.attrName) {

          // 半深拷贝   因为对方法没有作用

          // 把点击的数据转化为JSON数据
        let jsonRow =  JSON.stringify(row);
        //  把json数据转化为对象数据  并且把获取的点击的row数据 赋值给baseAttrInfo
        // baseAttrInfo  为需要收集的数据  发送保存
        this.baseAttrInfo = JSON.parse(jsonRow)
      }
      // 循环遍历获取的数据的数据值   并且在所有数据上添加setInput   
      // 因为这样则会进入就显示input输入框   离开时则会span只读
      this.baseAttrInfo.attrValueList.forEach(element => {
        // 在所有属性值中添加 setInput属性 并且值为true
        this.$set(element,'setInput',true)
      });
      // 如果点击了则隐藏属性列表  直接显示添加属性内容
      this.setFleg = false;
      // 点击了添加则把 子组件的选择框禁用
      this.setdisabled = true
    },
    // 点击取消按钮方法
    Cancel(){
      // 如果点击取消则显示属性列表  隐藏添加属性内容
       this.setFleg = true;
      //  把子组件的选择框取消禁用
       this.setdisabled = false;
      //  把需要收集内容的对象baseAttrInfo  清空
      //  因为如果二次点击会继续显示之前的内容
       this.baseAttrInfo =  {
          attrName: "", //属性名
          attrValueList: [  //多个属性值数据
        ],
          categoryId: this.category3Id,   //category3Id
          categoryLevel: 3, //默认为3
        }
    },

    // 添加属性按钮
    PustValue(){
      // 点击了添加属性按钮  则会出现输入框 与id  添加到收集数据内容里
      this.baseAttrInfo.attrValueList.push( {
          // 点击了修改则会有id  点击了添加则会为空
            attrId: this.baseAttrInfo.id, //属性id
            valueName: "",  //属性值
            setInput:true,
          })
        
      // 因为点击了页面还没反应过来   $nextTick页面更新完则调用该方法
      this.$nextTick(()=>{
        // 点击添加时  则输入框应该获取焦点  
        // 因为把添加的input输入框都设置了ref  获取实例   名为数字（$index）
            // this.$refs 其中还有另一个值  则需要-1    focus()获取焦点
           this.$refs[this.baseAttrInfo.attrValueList.length-1].focus()
      })
    },
    // 当添加属性input输入框 失去焦点则会调用该方法   接收当前移出的数据row
    RemoveOut(row){
      // 如果数据内容为空  则弹出禁告  并且 返回空 停止下面语句
       if (row.valueName == '') {
        this.$message({
          message: '警告，请不要填写空值',
          type: 'warning'
        });
        return 
      }

      // 判断输入的内容有没有相同的值
          // 获取所有对象的valueName值 返回的是数组
      // let array = this.baseAttrInfo.attrValueList.map((item)=>item.valueName)
        // 把数组转化为set  不显示重复的内容
      // let set = new Set(array);
      // 如果set的长度与添加的内容不相等则说明输入了相同的值
      // if (set.size!=array.length) {
        // 弹出警告  并且返回空
      //   this.$message({
      //     message: '警告，请不要填写重复值',
      //     type: 'warning'
      //   });
      //   return 
      // }

       // 判断输入的内容有没有相同的值
        // 如果一个符合为true  则会返回  不会继续执行
      let fleg = this.baseAttrInfo.attrValueList.some((item)=>{
        // 如果对象的引用不相等则会执行下面语句
        // 如果是====  则一开始则会true
        if (row !== item) {
          return row.valueName == item.valueName
        }
      })
      // 如果为ture 则说明重复
      if (fleg) {
         // 弹出警告  并且返回空
         this.$message({
          message: '警告，请不要填写重复值',
          type: 'warning'
        });
        return 
      }
      // 失去焦点时  则显示span 只读
      row.setInput=false
    },

    // 点击span只读时方法
    SerInputFocus(row,index){
      // 点击时 则显示input输入框  并且获得焦点
      row.setInput=true
      this.$nextTick(()=>{
        // 获得input的焦点
        this.$refs[index].focus();
      })
    },
    // 点击删除添加属性按钮的   删除按钮方法
    // 传入点击的内容的索引值
    DeleteRow(index){
      // 删除点击的索引的内容  1 为一个包括  如果为2  则会点击的内容 与后面一个   返回的值 会更改当前内容
      this.baseAttrInfo.attrValueList.splice(index,1)
    },

    // 点击保存按钮事件
    async Preserve(){
      let fleg = true;   //定义一个变量是否发生请求
      // 循环遍历attrValueList 属性值 有没有空值  
      this.baseAttrInfo.attrValueList.forEach((item)=>{
        // 判断有没有空值 如果有则fleg为false
        if (item.valueName == '') {
          fleg = false    
        }else{
          // 循环清除属性值中的  setInput属性
          delete item.setInput
        }
      })
      // 如果没有空值则发送请求
      if (fleg) {
        // 发送保存请求
        let result = await this.$API.attr.saveAttrInfo(this.baseAttrInfo)
        if(result.code == 200){
          // 如果成功则显示 属性值列表
            this.setFleg = true
            // 如果成功则 显示子组件的输入框文可选择
            this.setdisabled = false
            // 消息提示
            this.$message({
              message: '修改成功',
              type: 'success'
            });
            // 更新数据
            this.GetCategorySelectId({category1Id:this.category1Id,category2Id:this.category2Id,category3Id:this.category3Id})
            // 把所有数据清空  因为再次点击会保存之前的数据
            this.baseAttrInfo =  {
              attrName: "", //属性名
              attrValueList: [  //多个属性值数据
              ],
              categoryId: this.category3Id,   //category3Id
              categoryLevel: 3, //默认为3
            }
        }
      }else{
        // 如果失败 则弹出提交数据不能为空  返回空
        this.$message({
            message: '提交数据不能为空',
            type: 'warning'
          });
          return 
      }
    },

    // 点击属性值列表里的删除按钮 中确定是调用的方法
    async confirm(row){
      // 传入当前点击的内容
      // 发送删除当前点击的内容 接口 
       let result =  await this.$API.attr.deleteAttr(row.id)
      if (result.code==200) {
        // 如果成功则更新数据
        this.GetCategorySelectId({category1Id:this.category1Id,category2Id:this.category2Id,category3Id:this.category3Id})
      }
    }
  },
};
</script>

<style scoped>
/* 因为el-card会超出部分隐藏    组件select会被隐藏   */
.el-card{
  /* 取消超出部分隐藏 */
        overflow:visible !important;
    }
</style>